<template>
  <div class="app-container">
    <el-row :gutter="20">

      <supplierHeadTree :dataList="supplierList" @chooseTreeData="chooseTree"/>

      <!--用户数据-->
      <el-col :span="20" class="right">
        <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="110px">

          <el-form-item label="接口名称" prop="portName">
            <el-input
              v-model="queryParams.portName"
              placeholder="请输入接口名称"
              clearable
              size="small"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>

          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['pm:excPort:add']"
              :disabled="addDisabled"
            >新增
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['pm:excPort:remove']"
            >删除
            </el-button>
          </el-col>
          <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>

        <el-table v-loading="loading" :data="excPortList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center"/>
          <el-table-column label="id" align="center" prop="id" show-overflow-tooltip/>
          <el-table-column label="服务方名称" align="center">
            <template slot-scope="scope">
              {{ getSupplierName(scope.row.supplierId) }}
            </template>
          </el-table-column>
          <el-table-column label="接口名称" align="center" prop="portName" show-overflow-tooltip/>
          <el-table-column label="出参格式" align="center">
            <template slot-scope="scope">
              {{ getDataTypeName(scope.row.dataType) }}
            </template>
          </el-table-column>

          <el-table-column label="调用服务器地址" align="center" width="160px" prop="serverPath" show-overflow-tooltip/>
          <el-table-column label="报文编码" align="center" prop="dataCoding" show-overflow-tooltip/>
          <el-table-column label="请求方法" align="center" show-overflow-tooltip>
            <template slot-scope="scope">
              {{ getRequestName(scope.row.requestId) }}
            </template>
          </el-table-column>

          <el-table-column label="加密方法" align="center" show-overflow-tooltip>
            <template slot-scope="scope">
              {{ getEncryName(scope.row.encryId) }}
            </template>
          </el-table-column>


          <el-table-column label="cron表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true"/>
          <el-table-column label="超时时间（秒）" align="center" prop="timeOut" :show-overflow-tooltip="true"/>
          <el-table-column label="监控状态" align="center">
            <template v-if=scope.row.jobStatus !=null slot-scope="scope">
              <el-switch
                v-model="scope.row.jobStatus"
                active-value="0"
                inactive-value="1"
                @change="handleStatusChange(scope.row)"
              ></el-switch>
            </template>
          </el-table-column>

          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                icon="el-icon-edit"
                @click="handleUpdate(scope.row)"
                v-hasPermi="['pm:excPort:edit']"
              >修改
              </el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-delete"
                @click="handleDelete(scope.row)"
                v-hasPermi="['pm:excPort:remove']"
              >删除
              </el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-setting"
                @click="handleAddHeader(scope.row)"
              >配置Header
              </el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-setting"
                @click="handleJob(scope.row)"
              >监控配置
              </el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-setting"
                @click="handleRun(scope.row)"
              >执行一次
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination
          v-show="total>0"
          :total="total"
          :page.sync="queryParams.pageNum"
          :limit.sync="queryParams.pageSize"
          @pagination="getList"
        />
      </el-col>
    </el-row>

    <!-- 添加或修改服务方接口配置对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="700px" append-to-body>
      <el-form ref="form" class="addDialog" :model="form" :rules="rules" label-width="120px">

        <el-form-item label="接口名称" prop="portName">
          <el-input v-model="form.portName" placeholder="请输入接口名称"/>
        </el-form-item>

        <el-form-item label="出参格式" prop="dataType">
          <el-select v-model="form.dataType" placeholder="请选择出参格式">
            <el-option v-for="item in dataTypeArr" :key="item.value" :value="item.value" :label="item.name"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="调用服务器地址" prop="serverPath">
          <el-input v-model="form.serverPath" placeholder="请输入调用服务器地址"/>
        </el-form-item>

        <el-form-item label="报文编码" class="dataCoding" prop="dataCodingSuffix">
          <el-select v-model="form.dataCodingSuffix" value="form.dataCodingSuffix" placeholder="请选择报文编码">
            <el-option v-for="item in dataCodingType"
                       :key="item.value"
                       :value="item.label"
                       :label="item.label"
            ></el-option>
          </el-select>

          <el-select v-model="form.dataCodeCharset" value="form.dataCodeCharset" placeholder="请选择">
            <el-option
              v-for="item1 in charsetType"
              :key="item1.value"
              :value="item1.label"
              :label="item1.label"
            >
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="请求方法" prop="requestId">
          <!--          <el-input v-model="form.requestId" placeholder="请输入请求方法id"/>-->
          <el-select v-model="form.requestId" filterable placeholder="请选择请求方法id">
            <el-option v-for="item in chooseRequestIdList" :key="item.id" :value="item.id" :label="item.name"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="加密方法" prop="encryId">
          <el-select v-model="form.encryId" filterable placeholder="请选择加密方法id">
            <el-option label="请选择" value=""></el-option>
            <el-option v-for="item in chooseMainIdList" :key="item.id" :value="item.id" :label="item.name"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="超时时间（秒）" prop="timeOut">
          <el-input v-model="form.timeOut" placeholder="请输入超时时间"/>
        </el-form-item>


      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 添加或修改定时任务 -->
    <el-dialog :title="title" :visible.sync="openJob" width="700px" append-to-body>
      <el-form ref="formJob" class="addDialog" :model="form" :rules="rulesJob" label-width="120px">

        <el-form-item label="接口名称" prop="portName">
          <el-input v-model="form.portName" :disabled=true />
        </el-form-item>


        <el-form-item label="cron表达式" prop="cronExpression">
          <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
            <template slot="append">
              <el-button type="primary" @click="handleShowCron">
                生成表达式
                <i class="el-icon-time el-icon--right"></i>
              </el-button>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item label="监控状态">
          <el-radio-group v-model="form.jobStatus">
            <el-radio
              v-for="dict in dict.type.sys_job_status"
              :key="dict.value"
              :label="dict.value"
            >{{ dict.label }}
            </el-radio>
          </el-radio-group>
        </el-form-item>


      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFormJob">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
      <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
    </el-dialog>

    <!--  接口Header  -->
    <el-dialog :title="portHeader.title" :visible.sync="portHeader.open" width="1000px" append-to-body>
      <portHeader :portId="portId"/>
    </el-dialog>
  </div>
</template>

<script>
import {listExcPort, getExcPort, delExcPort, addExcPort, updateExcPort} from "@/api/pm/excPort";
import {listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus} from "@/api/monitor/job";

import {
  getAllistSupplierRequest
} from '@/api/pm/supplierRequest';

import {
  getAlllistSupplierMain
} from "@/api/pm/supplierMain";

import HeadTree from "@/components/HeadTree";
import supplierHeadTree from '@/components/HeadTree/supplier';
import supplier from '@/mixin/supplier';

import Crontab from '@/components/Crontab'
import portHeader from '@/views/pm/excPort/portHeader'


export default {
  name: "ExcPort",
  components: {HeadTree, supplierHeadTree, Crontab, portHeader},
  mixins: [supplier],
  dicts: ['sys_job_status'],
  data() {
    return {
      // 遮罩层
      loading: false,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 服务方接口配置表格数据
      excPortList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      openJob: false,
      // 传入的表达式
      expression: "",
      // 是否显示Cron表达式弹出层
      openCron: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        supplierId: null,
        portName: null,
        dataType: null,
        serverPath: null,
        dataCoding: null,
        requestId: null,
        encryId: null,
      },
      // 表单校验
      rules: {
        // supplierId: [
        //   {required: true, message: "服务方id不能为空", trigger: "blur"}
        // ],
        portName: [
          {required: true, message: "接口名称不能为空", trigger: "blur"}
        ],
        dataType: [
          {required: true, message: "出参格式不能为空", trigger: "change"}
        ],
        serverPath: [
          {required: true, message: "调用服务器地址不能为空", trigger: "blur"}
        ],
        // dataCodingSuffix: [
        //   {required: true, message: "报文编码不能为空", trigger: "blur"}
        // ],
        requestId: [
          {required: true, message: "请求方法id不能为空", trigger: "blur"}
        ],
      },
      rulesJob: {
        cronExpression: [
          {required: true, message: "cron表达式不能为空", trigger: "blur"}
        ],
        jobStatus: [
          {required: true, message: "监控任务状态不能为空", trigger: "change"}
        ],
      },

      // 服务方名称
      supplierName: '',
      // 选中的服务方id
      chooseSupplierId: '',
      // 选中的服务方类型
      chooseSupplierType: '',


      // 保文编码类型
      dataCodingType: [
        {label: 'application/json', value: 1},
        {label: 'text/plain', value: 2},
        {label: 'application/xml', value: 3},
        {label: 'application/x-www-form-urlencoded', value: 4}
      ],
      charsetType: [
        {label: 'UTF-8', value: 1},
        {label: 'GBK', value: 2}
      ],

      selectCharset: 'UTF-8',

      // 出参格式
      dataTypeArr: [
        {name: 'json', value: "1"},
        {name: 'xml', value: "2"}
      ],

      // 选中的服务方的请求方法id列表
      chooseRequestIdList: [],
      // 选中的服务方的加密方法id列表
      chooseMainIdList: [],

      // 是否允许新增
      addDisabled: true,
      supplierList: [],
      //表单参数
      form: {
        id: null,
        cronExpression: null,
        jobStatus: '1',
        supplierId: null,
        portName: null,
        dataType: null,
        serverPath: null,
        dataCoding: null,
        jobId: null,
        dataCodingSuffix: 'application/json',
        dataCodeCharset: 'UTF-8',
        timeOut: null,
        requestId: '',
        encryId: ''
      },
      job: {
        jobId: null,
        jobName: null,
        jobGroup: null,
        invokeTarget: null,
        cronExpression: null,
        status: null,
        concurrent: 1,
        misfirePolicy: 1,
      },
      // 显示配置供应商方法
      portId: '',
      portHeader: {
        title: '接口Header列表',
        open: false
      }
    };
  },
  watch: {
    'form.dataCodingSuffix': {
      handler(val) {
        // console.log('val为', val);
      },
      deep: true
    },
    'form.dataCodeCharset': {
      handler(val) {
        // console.log('val为', val);
      },
      deep: true
    }
  },
  computed: {
    getDataTypeName() {
      return function (type) {
        let obj = this.dataTypeArr.find(item => item.value == type);
        return obj.name;
      }
    },

    getSupplierName() {
      return function (supplierId) {
        if (this.supplierList) {
          return this.supplierList.find(item => item.supplierId == supplierId)?.supplierName || '';
        }

        return '';
      }
    }
  },
  methods: {

    /** 查询服务方接口配置列表 */
    getList() {
      this.loading = true;

      listExcPort(this.queryParams).then(response => {
        this.excPortList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },


    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        supplierId: null,
        portName: null,
        dataType: null,
        serverPath: null,
        dataCoding: null,

        dataCodingSuffix: 'application/json',
        dataCodeCharset: 'UTF-8',

        requestId: '',
        encryId: '',
        cronExpression: null,
        jobStatus: '1',
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");

      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {

      //判断是否已选择服务方
      let flag = this.judgeChooseSupplier();

      if (flag) {
        this.reset();
        this.open = true;
        this.title = "添加服务方接口配置";
        this.form.supplierId = this.chooseSupplierId;
        this.form.jobStatus = "0";

      } else {
        this.$message.error('请先选择要进行操作的服务方');
      }
    },

    // 判断是否已选择服务方
    judgeChooseSupplier() {
      return this.chooseSupplierId ? true : false;
    },

    // 获取服务方请求方法
    getSupplierRequestList() {
      getAllistSupplierRequest(this.chooseSupplierId).then(res => {
        if (res.code == 200) {
          const data = res.data ?? [];
          this.chooseRequestIdList = data.map(item => {
            return {
              ...item,
              name: `${item.name}_${item.supplierName}`
            }
          })
        }
      }).catch(error => {
        // console.log(error);
      });
    },

    // 获取服务方加密方法
    getSupplierMainList() {
      getAlllistSupplierMain(this.chooseSupplierId).then(res => {
        if (res.code == 200) {
          const data = res.data ?? [];
          this.chooseMainIdList = data.map(item => {
            return {
              ...item,
              name: `${item.name}_${item.supplierName}`
            }
          })
        }
      }).catch(error => {
        // console.log(error);
      });
    },


    /**
     * 更新操作
     * @param row
     */
    handleUpdate(row) {
      // this.reset();
      const id = row.id || this.ids;
      getExcPort(id).then(response => {
        this.form = response.data;

        const {dataCoding} = this.form;
        if (dataCoding != null) {
          const dataCodingArr = dataCoding.split(";");


          const dataCodingSuffix = dataCodingArr[0] || '';
          const dataCodeCharset = dataCodingArr[1] ? dataCodingArr[1].replace('charset=', '') : '';
          this.$set(this.form, 'dataCodingSuffix', dataCodingSuffix);
          this.$set(this.form, 'dataCodeCharset', dataCodeCharset);
        }

        this.chooseSupplierId = response.data.supplierId;
        this.open = true;
        this.title = "修改服务方接口配置";
      });
    },

    /**
     * 监控定时任务
     * @param row
     */
    handleJob(row) {
      this.reset();
      const id = row.id || this.ids;
      getExcPort(id).then(response => {
        this.form = response.data;
        if (this.form.jobStatus == null) {
          this.form.jobStatus = '1';
        }
        this.chooseSupplierId = response.data.supplierId;
        this.openJob = true;
        this.title = "监控任务";
      });
    },


    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id != null) {
            const {dataCoding, dataCodingSuffix, dataCodeCharset, ...param} = this.form;
            param.dataCoding = `${dataCodingSuffix};charset=${dataCodeCharset}`;
            updateExcPort(param).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            const {dataCodeCharset, dataCodingSuffix, ...param} = this.form;
            param.dataCoding = `${dataCodingSuffix};charset=${dataCodeCharset}`;
            addExcPort(param).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },

    /** 提交按钮 */
    submitFormJob() {
      this.$refs["formJob"].validate(valid => {
        if (valid) {
          this.job.jobId = this.form.jobId;
          this.job.cronExpression = this.form.cronExpression;
          this.job.status = this.form.jobStatus;
          if (this.form.jobId != null) {
            this.job.invokeTarget = 'portPostTask.sendPost(' + this.form.id + 'L)';
            this.job.cronExpression = this.form.cronExpression;
            this.job.status = this.form.jobStatus;
            updateJob(this.job).then(response => {
              this.form.jobId = response.data;
              return updateExcPort(this.form);
            }).then(() => {
              this.$modal.msgSuccess("修改成功");
              this.openJob = false;
              this.getList();
            }).catch(() => {
            });
          } else {
            this.job.jobName = this.form.portName + "监控任务";
            this.job.jobGroup = 'PM';
            this.job.invokeTarget = 'portPostTask.sendPost(' + this.form.id + 'L)';
            addJob(this.job).then(response => {
              this.form.jobId = response.data;
              return updateExcPort(this.form);
            }).then(() => {
              this.$modal.msgSuccess("修改成功");
              this.openJob = false;
              this.getList();
            }).catch(() => {
            });
          }
        }
      });
    },

    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除该服务方接口的数据？').then(function () {
        return delExcPort(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {
      });
    }
    ,
    /** 导出按钮操作 */
    handleExport() {
      this.download('pm/excPort/export', {
        ...this.queryParams
      }, `excPort_${new Date().getTime()}.xlsx`)
    }
    ,

    chooseTree(data) {
      // console.log('选择的服务方参数为', data);
      this.chooseSupplierId = data.id;

      // 判断新增按钮是否可点击
      this.addDisabled = !this.chooseSupplierId;
      this.chooseSupplierType = data.supplierType;

      // 获取选中的列表数据
      this.queryParams.supplierId = data.id || '';

      if (this.queryParams.supplierId) {
        this.getList();
      } else {
        this.excPortList = [];
        this.total = 0;
      }

      if (this.chooseSupplierId) {
        // 1. 根据服务方id获取请求方法
        this.getSupplierRequestList();
        // 2. 根据服务方id获取加密方法
        this.getSupplierMainList();
      }
    }
    ,

    getRequestName(requestId) {
      return this.chooseRequestIdList.find(d => d.id == requestId)?.name || '';
    }
    ,

    getEncryName(encryId) {
      return this.chooseMainIdList.find(d => d.id == encryId)?.name || '';
    }
    ,

    /** cron表达式按钮操作 */
    handleShowCron() {
      this.expression = this.form.cronExpression;
      this.openCron = true;
    }
    ,

    // 任务状态修改
    handleStatusChange(row) {
      let text = row.jobStatus === "0" ? "启用" : "停用";
      this.$modal.confirm('确认要"' + text + '""' + row.portName + '"监控任务吗？').then(function () {
        return changeJobStatus(row.jobId, row.jobStatus);
      }).then(() => {
        this.$modal.msgSuccess(text + "成功");
      }).catch(function () {
        row.jobStatus = row.jobStatus === "0" ? "1" : "0";
      });
    },

    /** 确定后回传值 */
    crontabFill(value) {
      this.form.cronExpression = value;
    },

    // 配置请求方法
    handleAddHeader(row) {
      // console.log(row);
      this.portId = row.id || '';
      this.portHeader.open = true;
    },

    /* 立即执行一次 */
    handleRun(row) {
      this.$modal.confirm('确认要立即执行一次"' + row.portName + '"监控任务吗？').then(function () {
        return runJob(row.jobId, 'PM');
      }).then(() => {
        this.$modal.msgSuccess("执行成功");
      }).catch(() => {
      });
    },

  }
}
;
</script>

<style lang="scss" scoped>
.addDialog {
  .dataCoding {
    ::v-deep .el-input--medium {
      width: 150px !important;
    }
  }
}
</style>
